﻿namespace DeltaGroup.WheelOfJeopardy.UI.Screens
{
    using System;
    using System.Windows.Controls;
    using System.Windows.Input;

    using DeltaGroup.WheelOfJeopardy.GameManager;
    using DeltaGroup.WheelOfJeopardy.Model;
    using DeltaGroup.WheelOfJeopardy.UI.Events;
    using DeltaGroup.WheelOfJeopardy.UI.ViewModel;

    /// <summary>
    /// Interaction logic for FinalJeopardyScreen.xaml
    /// </summary>
    public partial class FinalJeopardyScreen : UserControl, IFinalJeopardyUIManager
    {
        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="FinalJeopardyScreen"/> class.
        /// </summary>
        public FinalJeopardyScreen()
        {
            InitializeComponent();
        }

        #endregion Constructors

        #region Events

        /// <summary>
        /// Raised when a contestant has responded to challenge
        /// </summary>
        public event EventHandler<ChallengeResponseReceivedEventArgs> ChallengeResponseReceived;

        /// <summary>
        /// Raised when a contestant has failed to respond within time allowed
        /// </summary>
        public event EventHandler ResponseTimerExpired;

        /// <summary>
        /// Occurs when [wager received].
        /// </summary>
        public event EventHandler<WagerReceivedEventArgs> WagerReceived;

        #endregion Events

        #region Methods

        /// <summary>
        /// Prompts for response.
        /// </summary>
        /// <param name="challenge">The challenge.</param>
        /// <param name="secondsAllowed">The seconds allowed.</param>
        public void PromptForResponse(Challenge challenge, int secondsAllowed)
        {
            var challengeScreen = new ChallengePrompt() { DataContext = new ChallengePromptViewModel() { Challenge = challenge, TimeRemaining = secondsAllowed } };
            challengeScreen.ResponseReceived += (sender, args) => RaiseResponseReceived(args.Response);
            challengeScreen.ResponseTimerExpired += (sender, args) => RaiseResponseTimerExpired();

            ContentArea.Content = challengeScreen;

            challengeScreen.StartTimer();
        }

        /// <summary>
        /// Prompts for wager.
        /// </summary>
        /// <param name="maxAllowed">The max allowed.</param>
        public void PromptForWager(int maxAllowed)
        {
            var wagerScreen = new WagerScreen()
            {
                DataContext = new WagerModel
                {
                    MaxScore = maxAllowed
                }
            };

            ContentArea.Content = wagerScreen;
        }

        /// <summary>
        /// Determines whether this instance can exec the specified sender.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.CanExecuteRoutedEventArgs"/> instance containing the event data.</param>
        private void CanExec(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        /// <summary>
        /// Raises the response received.
        /// </summary>
        /// <param name="response">The response.</param>
        private void RaiseResponseReceived(string response)
        {
            if (ChallengeResponseReceived != null)
                ChallengeResponseReceived(this, new ChallengeResponseReceivedEventArgs(response));
        }

        /// <summary>
        /// Raises the response timer expired.
        /// </summary>
        private void RaiseResponseTimerExpired()
        {
            if (ResponseTimerExpired != null)
                ResponseTimerExpired(this, EventArgs.Empty);
        }

        /// <summary>
        /// Wagers the specified sender.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.ExecutedRoutedEventArgs"/> instance containing the event data.</param>
        private void Wager(object sender, ExecutedRoutedEventArgs e)
        {
            if (WagerReceived != null)
                WagerReceived(this, new WagerReceivedEventArgs((int)e.Parameter));
        }

        #endregion Methods
    }
}